package basics.iconcurrent;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * <span color="green" font-size="21px">内存可见性</span>&nbsp;导致的问题<br/>
 * 出现 {@code a = 1, b = 3}
 *
 * @author or2
 * @date 2021/8/6 17:40
 */
public class FieldVisibleDemo {

    private int a = 1;
    private int b = 2;

    private void change() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        a = 3;
        b = a;
    }

    private void print() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("a = " + a + ", b = " + b);
    }

    /**
     * 隐藏的第四种情况 - <var>a</var> = 1; <var>b</var> = 3 - <span color="orange">单线程内有序, 但是读出了脏数据导致问题出现</span>
     *
     * @param args 入参
     */
    public static void main(String[] args) {
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        availableProcessors *= 2;
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(availableProcessors, availableProcessors
                , 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

        int index = 0;
        do {
            FieldVisibleDemo demo = new FieldVisibleDemo();
            index++;

            threadPoolExecutor.submit(demo::change);
            threadPoolExecutor.submit(demo::print);
        } while (index < 1e6);
        threadPoolExecutor.shutdown();
    }

}
